perm filename INGLUK.MAC[IP,SYS] blob
sn#680208 filedate 1982-10-14 generic text, type T, neo UTF8
;CWL:<403-INET>INGLUK.MAC.40303 12-Apr-82 21:02:57, Edit by CLYNN
; Written for Multinet/Internet, GWYLUK just returns address in T1
SEARCH PROLOG
TTITLE INGLUK
SUBTTL Gateway Table Accessing and Updating Routines
SWAPCD
SEARCH INPAR ; Get Internet definitions
IFN MNET,<
SEARCH MNTPAR ; Get Multinet definitions
>
COMMENT !
Dan Tappan 2/82
This module contains routines for maintaining and accessing
net<->gateway tables.
It exports the following routines:
* GWYLUK .. 3 .. Look up a gateway address for a given destination.
* INTUP ... 5 .. Report an interface as up.
* INTDWN .. 6 .. Report an interface as down.
* GWYDWN .. 7 .. Report a gateway as down.
* NETHSI .. 8 .. Initialize the network hash table.
* NETHSH .. 9 .. Hash a net number into the lookup table.
It imports the following:
FNDGWY INCMP Find a gateway to get to a given network.
!
;;; GWYLUK -- Look up a gateway address for a given destination.
;;; Accepts T1/ 32 bit destination address
;;; Returns T1/ 0 if no path to the destination, or
;;; Interface# & Address of a gateway/host on a
;;; connected network that can gateway to that
;;; destination (may be the same destination)
;;; T2/ Garbage
;;; T3/ If system runs Multinet, garbage; otherwise
;;; the interface index to use (-1,,index).
;;; P1/ If system runs multinet the address of the
;;; NCT for an interface to use ((0 or -1),,index)
;;; 0 if no path
GWYLUK::ACVAR <NET>
NETNUM T2,T1 ; Get the network number
MOVEM T2,NET ; Save number
CALL NETHSH ;(T2 to T2, killing 3,4); Hash the network into tables
JRST LUKNIT ; not in the tables
IFE MNET,<
SKIPGE T3,NETGWY(T2) ; Gateway address?
RET ; -1,,index ; No, return with interface
JUMPE T3,LUKNIT ; Deleted entry
; Found gateway
MOVE T1,T3 ; get host address
>
IFN MNET,<
SKIPGE P1,NETGWY(T2) ; Gateway?
RET ; -1,,.NCTi ; No, return with interface
JUMPE P1,LUKNIT ; Deleted entry
; Found gateway
MOVE T1,P1 ; get address
>
GWYL5: LOAD T3,INTNUM,+T1 ; get interface index
IFN MNET,<
MOVE P1,NCTVT(T3) ; get NCT address
>
TLN T1,740000 ; Just 32-bit address
RET ; and return with it
;;; Here if there is no entry in the network tables
;;; for that net.
;;; T1/ destination, T2/ net hash index of empty slot in NETGWY
LUKNIT: PUSH P,T2 ; Save hash table index
CALL FNDGWY ; Find a gateway
JUMPE T1,[POP P,T2 ; Restore hash address
RET] ; Return unsucessfully
CALL FNDNCT ; Find interface for this one
INBUG (HLT,<FNDGWY returned unconnected gateway>,GWYFNB)
IFN MNET,<
LOAD T2,NTNUM,(P1) ; Get interface index
>
STOR T2,INTNUM,+T1 ; save interface index
POP P,T2 ; restore hash address
MOVEM T1,NETGWY(T2) ; place gateway in tables
JRST GWYL5 ; and join above
; ENDAV.
;;; INTUP -- Signal that an interface has come up
;;; Called T1/ Interface index (if not multinet)
;;; P1/ NCT address (If multinet)
INTUP::
IFN MNET,<
MOVE T2,NTNET(P1) ; get network number
>
IFE MNET,<
TXO T1,1B0 ; flag it
PUSH P,T1 ; save entry
MOVE T1,NLHOST(T1) ; get host number
NETNUM T2,T1 ; And the net number from it
>
CALL NETHSH ; hash the entry
NOP ; ignore failure
IFN MNET,<
HRROM P1,NETGWY(T2) ; save NCT
>
IFE MNET,<
POP P,NETGWY(T2) ; drop in index
>
RET ; and return
;;; INTDWN -- Signal that an interface has gone down.
;;; Called P1/ NCT for the interface (if multinet)
;;; T1/ Interface index (if not)
INTDWN::SAVET
STKVAR <INDEX> ; interface index
IFE MNET,<
MOVEM T1,INDEX ; save index
MOVE T1,NLHOST(T1) ; get address
NETNUM T2,T1 ; Get the net number
>
IFN MNET,<
MOVE T1,NTLADR(P1) ; Get our address
MOVE T2,NTNET(P1) ; and it's net number
>
CALL NETHSH ; Hash it
INBUG (HLT,<INTDWN -- Impossible failure of NETHSH>,INTDHF)
SETZM NETGWY(T2) ; don't use this interface
IFN MNET,<
LOAD T2,NTNUM,(P1) ; Get the internal index
MOVEM T2,INDEX ; Save it
>
MOVSI T2,-NETHSZ ; size of hash table
;;; INDEX has interface index
;;; T2 has index into hash table
INTDWL: SKIPG T1,NETGWY(T2) ; Anything in this slot?
JRST INTDL2 ; no, onward
LOAD T4,INTNUM,+T1 ; get index of this number
CAME T4,INDEX ; Same interface?
JRST INTDL2 ; mark it down
SETZM NETGWY(T2) ; erase that entry
INTDL2: AOBJN T2,INTDWL ; loop through the table
RET ; and return
;;; GWYDWN -- Signal that a gateway has crashed.
;;; Called T1/ Address of gateway
;;; Returns T2,T3 clobbered
;;; all paths using this gateway erased.
GWYDWN::
MOVSI T2,-NETHSZ ; Size of the hash tables
GWYDWL: SKIPG T3,NETGWY(T2) ; get address
JRST GWYDW2 ; None there
TXZ T3,-1B3 ; Clear the index field
CAMN T1,T3 ; this gateway a path to there?
SETZM NETGWY(T2) ; Yes, flush it
GWYDW2: AOBJN T2,GWYDWL ; Loop through the table
RET ; and return
;;; NETHSI -- Initialize the network hash table
;;; Called at system startup, whenever the hash table
;;; overflows, and at random times to flush unused
;;; table entries
NETHSI::
IFN MNET,<SAVP1>
NOSKED ; Take over the machine
SETZM NETHTB ; Clear
MOVE T1,[XWD NETHTB,NETHTB+1]
BLT T1,NETHTB+NETHSZ ; The entire table
SETZM NETGWY ; And
MOVE T1,[XWD NETGWY,NETGWY+1]
BLT T1,NETGWY+NETHSZ ; the parallel table
IFN MNET,<
XMOVEI P1,NCTVT ; Point to NCT vector table
NETHI0: LOAD P1,NTLNK,(P1) ; get next in chain
JUMPE P1,NETHIX ; done
MOVE T2,NTNET(P1) ; get the net number
CALL NETHSH ; Hash it into tables
NOP ; Ignore return
SKIPE NTORDY(P1) ; If this network is usable
HRROM P1,NETGWY(T2) ; Set it as the path to this net
JRST NETHI0 ; And loop through all interfaces
>
IFE MNET,<
MOVSI T4,-%NETS ; Number of interfaces
NETHI0: MOVE T1,NLHOST(T4) ; Get an address
NETNUM T2,T1 ; extract the network number
CALL NETHSH ; hash it into the tables
NOP ; ignore return
HRROM T4,NETGWY(T2) ; Save the address
AOBJN T4,NETHI0 ; and loop through all
>
NETHIX: OKSKED ; Allow use of the machine
RET ; return when done
;;; NETHSH -- Look up a netwrk number in the hash tables
;;; Called
;;; T2/ network number
;;; Returns
;;; T2/ Slot in the table for that network
;;; Clobbers T3, T4
;;; +1 if no entry currently there
;;; (the slot is reserved in that case)
;;; +2 if that network already has a slot in the tables
NETHSH::ACVAR <NET> ; net number
MOVE NET,T2 ; Save it here
IDIVI T2,NETHSZ ; Make the initial probe
EXCH T2,T3 ; ...
NOSKED ; protect the table
;;; The following is an optimization for the
;;; (hopefully common) case where there is no collision
;;; and/or the entry is already in the table.
CAMN NET,NETHTB(T2) ; Same entry?
JRST NETHSS ; Success, go use it
SKIPN NETHTB(T2) ; Empty?
JRST NETHSF ; First probe failed
IDIVI T3,NETHSZ ; divide again to get the delta
SKIPN T4 ; If there is none
MOVEI T4,1 ; use 1
MOVEI T3,NETHSZ-1 ; size of the tables
;;; At this point T2 holds the current probe, T4 holds the delta,
;;; T3 holds the number of attempts before deciding the table is full.
;;; The current table slot is not this net.
NETHSL: ADDI T2,(T4) ; Add in the delta
CAIL T2,NETHSZ ; Overflow?
SUBI T2,NETHSZ ; back up
CAMN NET,NETHTB(T2) ; Same net?
JRST NETHSS ; found it
SKIPN NETHTB(T2) ; Slot in use?
JRST NETHSF ; Empty, use it
SOJG T3,NETHSL ; loop through the table
;;; Here if the table is full.
;;; we reinitialize the table, since we assume that the
;;; table is large enough to hold all networks with active connections.
CALL NETHSI ; re-init the table
MOVE T2,NET ; Get the network number back
CALL NETHSH ; hash it
INBUG (HLT,<Impossible failure of NETHSH>,NTHSHF)
;;; Here if an entry is found
NETHSS: OKSKED ; Allow scheduling again
RETSKP ; return success
;;; Here if there is no entry for this net
NETHSF: MOVEM NET,NETHTB(T2) ; Reserve a table slot
OKSKED
RET ; return failure
; ENDAV.
IFE MNET,<
;;; Dummy routines used if system is not running the Multinet software
;;; FNDNCT -- Find the interface for a given host address
;;; Called T1/ 32 bit address
;;; Returns +2 if host has an interface on that machine, with T3
;;; holding the index
;;; Dummy routine always assumes success.
FNDNCT::
SETZ T3, ; Assume 0
RETSKP ; return good
> ; End of dummy routines
TNXEND
END
; Local Modes:
; Mode:Macro
; Comment C